#ifndef __SYLAR_TIMER_H__
#define __SYLAR_TIMER_H__

#include <memory>
#include <set>
#include <vector>
#include <functional>

#include "thread.h"


namespace sylar
{

class TimerManger;

class Timer : public std::enable_shared_from_this<Timer>
{

    friend class TimerManger;
public:
    using ptr = std::shared_ptr<Timer>;


public:
    Timer(uint64_t ms, std::function<void(void)> cb, bool recurring, TimerManger* manger);
    Timer(uint64_t next);

    bool cancel();
    bool refresh();
    bool reset(uint64_t ms, bool from_now);

private:
    bool m_recurring;   // 是否循环
    uint64_t m_ms = 0;              // 循环周期 
    uint64_t m_next = 0;            // 精确的执行时间
    TimerManger* m_manger = nullptr;
    std::function<void(void)> m_cb;

private:
    struct Comparator
    {
        bool operator() (const Timer::ptr& lhs, const Timer::ptr& rhs) const;
    };
    
};


class TimerManger
{
    friend class  Timer;

public:
    using RWMutexType = RWMutex;

    TimerManger();
    virtual ~TimerManger();

    Timer::ptr addTimer(uint64_t ms, std::function<void(void)> cb, bool recurring = false);

    // 条件定时器 weak_cond 存在时执行
    Timer::ptr addConditionTimer(uint64_t ms, std::function<void(void)> cb, std::weak_ptr<void> weak_cond, bool recurring = false);

    uint64_t getNextTimer();

    // 已经过时的
    void listExpiredCb(std::vector<std::function<void(void)>>& cbs);

    bool hasTimer();

protected:
    virtual void onTimerInserFront() = 0;

    void addTimer(Timer::ptr val, RWMutexType::WriteLock& lock);

private:
    bool detectClockRollover(uint64_t now_ms); 

private:
    RWMutexType m_mutx;
    std::set<Timer::ptr, Timer::Comparator> m_timers;
    bool m_tickled = false;

    uint64_t m_previoseTime = 0;
};



}
#endif